package cn.tianyigps.tianyigpsynclean.hanlder;

import cn.tianyigps.tianyigpspublic.param.bo.Task;
import cn.tianyigps.tianyigpspublic.param.constant.CollectionNameConstant;
import cn.tianyigps.tianyigpspublic.param.constant.EquipmentReceiveConstant;
import cn.tianyigps.tianyigpspublic.util.FormatUtil;
import cn.tianyigps.tianyigpspublic.bean.EquipmentHistory;
import cn.tianyigps.tianyigpspublic.bean.EquipmentLastData;
import cn.tianyigps.tianyigpspublic.param.bo.EquipmentParamBO;
import cn.tianyigps.tianyigpsynclean.dao.DataCleanDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: WEI.YUAN
 * @Descirption:数据清洗实现类
 * @Date: 2019/4/24_17:01
 */
@Component
@Slf4j
public class CleanHanlder {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    DataCleanDao dataCleanDao;

    @Autowired
    DataCheckHandler distributeTask;

    /**
     * 数据清洗
     *
     * @param task
     */
    public void dataClean(Task task) {
        //校检是否为第一条数据
        EquipmentLastData eqLastDataList = getEqLastData(task);

        //状态校检，分发任务
        if (eqLastDataList != null) {
            //有历史数据则对比并分发
            distributeTask.checkData(eqLastDataList, task);
        } else {
            //无历史数据直接存储
            insertEquipmentLast(task.getParams());
        }
        //保存轨迹
        insertEquipmentHistory(task.getParams());
    }


    /**
     * 校检新增轨迹数据是否为新增数据
     *
     * @param task
     * @return
     */
    public EquipmentLastData getEqLastData(Task task) {
        Map<String, String> taskMap = task.getParams();
        String equipmentId = taskMap.get(EquipmentReceiveConstant.DeviceCode);
        //先从缓存中取出最后一条位置变化信息
        String key = equipmentId + "lastlocation";
        EquipmentLastData eqLastDataList = (EquipmentLastData) redisTemplate.opsForValue().get(key);

        if (eqLastDataList == null) {
            //如果缓存中取出的信息为空则去数据库中取出并放入缓存中
            eqLastDataList = dataCleanDao.findEqById(equipmentId);

            if (eqLastDataList != null) {
                redisTemplate.opsForValue().set(key, eqLastDataList);
            }
        }
        return eqLastDataList;
    }


    /**
     * 新增equipmentlastdata
     *
     * @param taskMap
     */
    public void insertEquipmentLast(Map<String, String> taskMap) {
        EquipmentLastData equipmentLastData = new EquipmentLastData();

        equipmentLastData.setSignalTime(FormatUtil.stampToDate(taskMap.get(EquipmentReceiveConstant.UpTime)));
        equipmentLastData.setEquipmentId(taskMap.get(EquipmentReceiveConstant.DeviceCode));
        equipmentLastData.setCreateTime(new Date());

        //设备参数集合
        Map<String, EquipmentParamBO> equipmentParamBOMap = new HashMap<>();
        //设备经纬度集合
        Map<String, Object> equipmentLongLatMap = new HashMap<>();

        taskMap.forEach((status, object) -> {
            EquipmentParamBO eq = new EquipmentParamBO();

            if (status.equals(EquipmentReceiveConstant.Latitude) || status.equals(EquipmentReceiveConstant.Longitude)) {
                equipmentLongLatMap.put(EquipmentReceiveConstant.Latitude, Double.valueOf(taskMap.get(EquipmentReceiveConstant.Latitude)));
                equipmentLongLatMap.put(EquipmentReceiveConstant.Longitude, Double.valueOf(taskMap.get(EquipmentReceiveConstant.Longitude)));
                equipmentLongLatMap.put("time", FormatUtil.stampToString(taskMap.get(EquipmentReceiveConstant.UpTime)));
            } else {
                eq.setKey(status);
                eq.setValue(object);
                eq.setTime(FormatUtil.stampToString(taskMap.get(EquipmentReceiveConstant.UpTime)));
                equipmentParamBOMap.put(status, eq);
            }
        });

        equipmentLastData.setParams(equipmentParamBOMap);
        equipmentLastData.setMaps(equipmentLongLatMap);

        try {
            dataCleanDao.insertEquipmentLast(equipmentLastData, CollectionNameConstant.EQUIPMENT_LAST_DATA);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("新增equipmentLastData出错:{}", e);
        }
    }

    /**
     * 新增equipmenthistory
     *
     * @param taskMap
     */
    public void insertEquipmentHistory(Map<String, String> taskMap) {
        EquipmentHistory equipmentHistory = new EquipmentHistory();
        equipmentHistory.setCreateTime(new Date());
        equipmentHistory.setEquipmentId(taskMap.get(EquipmentReceiveConstant.DeviceCode));
        equipmentHistory.setSignalTime(FormatUtil.stampToDate(taskMap.get(EquipmentReceiveConstant.UpTime)));

        //参数数据
        Map<String, String> paramsMap = new HashMap<>();
        //经纬度数据
        Map<String,Double>  maps = new HashMap<>();

        taskMap.forEach((status, object) -> {
            if(status.equals(EquipmentReceiveConstant.Longitude)||status.equals(EquipmentReceiveConstant.Latitude)){
                maps.put(status,Double.valueOf(object));
            }else{
                paramsMap.put(status, object);

            }
        });
        equipmentHistory.setParams(paramsMap);

        if(!CollectionUtils.isEmpty(maps)){
            equipmentHistory.setMaps(maps);
        }
        try {
            dataCleanDao.insertEquipmentHisttory(equipmentHistory, CollectionNameConstant.EQUIPMENT_HISTORY);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("新增equipmentHistory出错:{}", e);
        }

    }
}
